package org.light.simpleauth;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.light.complexverb.AddUploadDomainField;
import org.light.complexverb.DomainFieldVerb;
import org.light.complexverb.UpdateUploadDomainField;
import org.light.core.PrismInterface;
import org.light.core.Verb;
import org.light.domain.Controller;
import org.light.domain.Dao;
import org.light.domain.DaoImpl;
import org.light.domain.Domain;
import org.light.domain.DomainFieldController;
import org.light.domain.Dropdown;
import org.light.domain.Field;
import org.light.domain.LoginController;
import org.light.domain.ManyToMany;
import org.light.domain.Method;
import org.light.domain.Prism;
import org.light.domain.ProfileController;
import org.light.domain.Project;
import org.light.domain.Service;
import org.light.domain.ServiceImpl;
import org.light.domain.TwoDomainController;
import org.light.domain.Type;
import org.light.domain.ValidateInfo;
import org.light.easyuilayouts.EasyUIMtmPI;
import org.light.easyuilayouts.widgets.Nav;
import org.light.exception.ValidateException;
import org.light.generator.NamedUtilMethodGenerator;
import org.light.limitedverb.CountActiveRecords;
import org.light.limitedverb.CountAllRecords;
import org.light.limitedverb.CountSearchByFieldsRecords;
import org.light.limitedverb.DaoOnlyVerb;
import org.light.limitedverb.NoControllerVerb;
import org.light.simpleauth.easyui.EasyUIErrorPI;
import org.light.simpleauth.easyui.EasyUILoginUserIndexPI;
import org.light.simpleauth.easyui.EasyUIProfilePI;
import org.light.simpleauth.easyui.EasyUIRegisterUserPI;
import org.light.simpleauth.easyui.EasyUIUserPagePI;
import org.light.simpleauth.easyui.NoAuthPIGenerator;
import org.light.simpleauth.verb.AddUser;
import org.light.simpleauth.verb.ChangeMyPasswordUser;
import org.light.simpleauth.verb.ChangePasswordUser;
import org.light.simpleauth.verb.CountSaltUser;
import org.light.simpleauth.verb.FindMyProfileUser;
import org.light.simpleauth.verb.FindUserShadow;
import org.light.simpleauth.verb.LoginUser;
import org.light.simpleauth.verb.LogoutUser;
import org.light.simpleauth.verb.ReadMySession;
import org.light.simpleauth.verb.RegisterUser;
import org.light.simpleauth.verb.UpdateMyProfileUser;
import org.light.utils.DomainUtil;
import org.light.utils.FieldUtil;
import org.light.utils.PasswordUtil;
import org.light.utils.StringUtil;
import org.light.verb.Activate;
import org.light.verb.ActivateAll;
import org.light.verb.CheckAccess;
import org.light.verb.Clone;
import org.light.verb.CloneAll;
import org.light.verb.Delete;
import org.light.verb.DeleteAll;
import org.light.verb.Export;
import org.light.verb.ExportPDF;
import org.light.verb.ExportPPT;
import org.light.verb.ExportWord;
import org.light.verb.FilterExcel;
import org.light.verb.FilterPDF;
import org.light.verb.FilterPPT;
import org.light.verb.FilterWord;
import org.light.verb.FindById;
import org.light.verb.FindByName;
import org.light.verb.FindFullInfoById;
import org.light.verb.ListActive;
import org.light.verb.ListAll;
import org.light.verb.SearchByFields;
import org.light.verb.SearchByFieldsByPage;
import org.light.verb.SearchIndexedNamesByShortName;
import org.light.verb.SoftDelete;
import org.light.verb.SoftDeleteAll;
import org.light.verb.Toggle;
import org.light.verb.ToggleOne;
import org.light.verb.Update;
import org.light.verb.View;

public class SimpleAuthModule extends org.light.core.Module{
	protected Domain userDomain;
	protected Domain roleDomain;
	protected Domain privilegeDomain;
	protected Prism loginPrism;
	protected Prism profilePrism;
	protected Prism userPrism;
	protected Prism rolePrism;
	protected Prism privilegePrism;
	protected String generateData = "whennecessary";
	protected Map<String,Boolean> slavesMap = new TreeMap<>();
	
	public SimpleAuthModule() {
		super();
		this.standardName = "SimpleAuth";
	}
	
	public boolean validateDomains() throws ValidateException{
		ValidateInfo info = new ValidateInfo();
		if (userDomain==null||roleDomain==null||privilegeDomain==null) {
			info.addCompileError("所需域对象缺失！");			
		}
		if (userDomain.findFieldByFixedName("userName")==null||!userDomain.findFieldByFixedName("userName").getFieldType().equalsIgnoreCase("String")) {
			info.addCompileError("用户域对象固定名字userName字段设置有问题！");			
		}
		if (userDomain.findFieldByFixedName("password")==null||!userDomain.findFieldByFixedName("password").getFieldType().equalsIgnoreCase("String")
				||(!StringUtil.isBlank(userDomain.findFieldByFixedName("password").getLengthStr())&&Integer.parseInt(userDomain.findFieldByFixedName("password").getLengthStr())<40)){
			info.addCompileError("用户域对象固定名字password字段设置有问题！");			
		}	
		if (userDomain.findFieldByFixedName("salt")==null||!userDomain.findFieldByFixedName("salt").getFieldType().equalsIgnoreCase("String")
				||(!StringUtil.isBlank(userDomain.findFieldByFixedName("salt").getLengthStr())&&Integer.parseInt(userDomain.findFieldByFixedName("salt").getLengthStr())<8)){
			info.addCompileError("用户域对象固定名字salt字段设置有问题！");			
		}	
		if (userDomain.findFieldByFixedName("loginFailure")==null||!(userDomain.findFieldByFixedName("loginFailure").getClassType().getTypeName().equalsIgnoreCase("int")||userDomain.findFieldByFixedName("loginFailure").getClassType().getTypeName().equalsIgnoreCase("Integer")||userDomain.findFieldByFixedName("loginFailure").getClassType().getTypeName().equalsIgnoreCase("Long"))){
			info.addCompileError("用户域对象固定名字loginFailure字段设置有问题！");			
		}	
//		if (roleDomain.findFieldByFixedName("roleName")==null||!roleDomain.findFieldByFixedName("roleName").getFieldType().equalsIgnoreCase("String")) {
//			info.addCompileError("角色域对象roleName字段设置有问题！");			
//		}		
		if (info.success(true))	return true;
		else throw new ValidateException(info);
	}
	
	public boolean validateDataDomains() throws ValidateException{
		ValidateInfo info = new ValidateInfo();
		if (info.success(true))	return true;
		else throw new ValidateException(info);
	}

	@Override
	public void generateModuleFiles(String targetFolderPath, Boolean genUi, Boolean genController,
			Boolean genService, Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl) throws Exception {
		this.setPrisms(new ArrayList<>());
		this.addPrism(this.loginPrism);
		this.addPrism(this.userPrism);
		this.addPrism(this.rolePrism);
		this.addPrism(this.privilegePrism);
		this.addPrism(this.profilePrism);
		
		slavesMap.remove(this.userDomain.getStandardName());
		slavesMap.remove(this.roleDomain.getStandardName());
		slavesMap.remove(this.privilegeDomain.getStandardName());
		slavesMap.remove(this.profilePrism.getStandardName());
		
		for (Prism p:this.getPrisms()) {
			setFolderPath(targetFolderPath);
			generatePrismFiles(p,slavesMap,true,genUi, genController,
					genService, genServiceImpl, genDao, genDaoImpl);
		}
		
		PasswordUtilGenerator pwdg = new PasswordUtilGenerator(this.userDomain);
		writeToFile(targetFolderPath +"src/"+Project.packagetokenToFolder(this.userDomain.getPackageToken())+"utils/"  +pwdg.getFileName(),
				pwdg.generateStatementList().getContent());
		
		AppTokenManagerGenerator atmg = new AppTokenManagerGenerator(this.userDomain);
		writeToFile(targetFolderPath +"src/"+Project.packagetokenToFolder(this.userDomain.getPackageToken())+"utils/"  +atmg.getFileName(),
				atmg.generateStatementList().getContent());
	}
	
	public void generateDummyModuleFiles(String targetFolderPath, Boolean genUi, Boolean genController,
			Boolean genService, Boolean genServiceImpl, Boolean genDao, Boolean genDaoImpl) throws Exception {
		this.setPrisms(new ArrayList<>());
		this.addPrism(this.loginPrism);
		this.addPrism(this.userPrism);
		this.addPrism(this.rolePrism);
		this.addPrism(this.privilegePrism);
		this.addPrism(this.profilePrism);
		
		slavesMap.remove(this.userDomain.getStandardName());
		slavesMap.remove(this.roleDomain.getStandardName());
		slavesMap.remove(this.privilegeDomain.getStandardName());
		slavesMap.remove(this.profilePrism.getStandardName());
		
		for (Prism p:this.getPrisms()) {
			setFolderPath(targetFolderPath);
			generateDummyPrismFiles(p,slavesMap,true,genUi, genController,
					genService, genServiceImpl, genDao, genDaoImpl);
		}
		
		PasswordUtilGenerator pwdg = new PasswordUtilGenerator(this.userDomain);
		writeToFile(targetFolderPath +"src/"+Project.packagetokenToFolder(this.userDomain.getPackageToken())+"utils/"   +pwdg.getFileName(),
				pwdg.generateStatementList().getContent());
	}

	@Override
	public void generatePrismsFromDomains() throws Exception {
		if ("MariaDB".equalsIgnoreCase(this.dbType)||"MySQL".equalsIgnoreCase(this.dbType)||"pgsql".equalsIgnoreCase(this.dbType)||"PostgreSQL".equalsIgnoreCase(this.dbType)||"Oracle".equalsIgnoreCase(this.dbType)) {
			ValidateInfo info = new ValidateInfo();
			if (this.userDomain instanceof org.light.domain.Enum) {
				info.addCompileError("用户域对象"+this.userDomain.getStandardName()+"不可以是枚举。");
			}
			if (this.roleDomain instanceof org.light.domain.Enum) {
				info.addCompileError("角色域对象"+this.roleDomain.getStandardName()+"不可以是枚举。");
			}
			if (this.privilegeDomain instanceof org.light.domain.Enum) {
				info.addCompileError("权限域对象"+this.privilegeDomain.getStandardName()+"不可以是枚举。");
			}
			if (this.userDomain.isLegacy()) {
				info.addCompileError("用户域对象"+this.userDomain.getStandardName()+"不可以是遗留域对象。");
			}
			if (this.roleDomain.isLegacy()) {
				info.addCompileError("角色域对象"+this.roleDomain.getStandardName()+"不可以是遗留域对象。");
			}
			if (this.privilegeDomain.isLegacy()) {
				info.addCompileError("权限域对象"+this.privilegeDomain.getStandardName()+"不可以是遗留域对象。");
			}
			if (!this.userDomain.getDomainName().getFieldName().equals(this.userDomain.findFieldByFixedName("userName").getFieldName())) {
				info.addCompileError("用户域对象"+this.userDomain.getStandardName()+"的名字字段固定名字一定要设为userName。");
			}
			if (!info.success(true)) throw new ValidateException(info);
			Prism loginPrism = new Prism();	
			loginPrism.setDomain(this.userDomain);
			loginPrism.setStandardName("LoginPrism");
			loginPrism.setDbType(this.dbType);
			loginPrism.setPackageToken(this.getPackageToken());
			this.loginPrism = loginPrism;
			this.loginPrism.setTitle(this.title);
			this.loginPrism.setSubTitle(this.subTitle);
			this.loginPrism.setFooter(this.footer);
			this.loginPrism.setTechnicalStack(this.technicalstack);

			Prism userPrism = new Prism();
			userPrism.setDomain(this.userDomain);
			userPrism.setStandardName("UserPrism");
			//userPrism.setDbType(this.dbType);
			userPrism.setPackageToken(this.getPackageToken());
			Set<Domain> projectDomains = new TreeSet<>();
			projectDomains.addAll(this.domains);
			userPrism.setProjectDomains(projectDomains);			
			this.userPrism = userPrism;

			generateLoginPrismFromUserDomain(true);
			decorateLoginPrism();
			
			Set<Field> deniedFields = new TreeSet<>();
			deniedFields.add(this.userDomain.findFieldByFixedName("password"));
			deniedFields.add(this.userDomain.findFieldByFixedName("salt"));
			deniedFields.add(this.userDomain.findFieldByFixedName("loginFailure"));
			
			Prism profilePrism = new Prism();	
			profilePrism.setDomain(this.userDomain);
			profilePrism.setStandardName("ProfilePrism");
			this.profilePrism = profilePrism;
			this.profilePrism.setTitle(this.title);
			this.profilePrism.setSubTitle(this.subTitle);
			this.profilePrism.setFooter(this.footer);
			this.profilePrism.setTechnicalStack(this.technicalstack);
			generateProfilePrismFromUserDomainWithDeniedFields(true,deniedFields);			

			this.userPrism.setTitle(this.title);
			this.userPrism.setSubTitle(this.subTitle);
			this.userPrism.setFooter(this.footer);
			this.userPrism.setTechnicalStack(this.technicalstack);
			decorateUserPrism();

			generateUserPrismFromUserDomainWithDeniedFields(true,deniedFields);
			
			Prism rolePrism = new Prism();	
			rolePrism.setTitle(this.title);
			rolePrism.setSubTitle(this.subTitle);
			rolePrism.setFooter(this.footer);
			rolePrism.setDomain(this.roleDomain);
			rolePrism.setStandardName("RolePrism");
			rolePrism.setDbType(this.dbType);
			rolePrism.setPackageToken(this.getPackageToken());
			rolePrism.setProjectDomains(projectDomains);
			rolePrism.setTechnicalStack(this.technicalstack);
			rolePrism.generatePrismFromDomain(true);
			
			Prism privilegePrism = new Prism();
			privilegePrism.setTitle(this.title);
			privilegePrism.setSubTitle(this.subTitle);
			privilegePrism.setFooter(this.footer);
			privilegePrism.setDomain(this.privilegeDomain);
			privilegePrism.setStandardName("PrivilegePrism");
			privilegePrism.setDbType(this.dbType);
			privilegePrism.setPackageToken(this.getPackageToken());
			privilegePrism.setProjectDomains(projectDomains);
			privilegePrism.setTechnicalStack(this.technicalstack);
			privilegePrism.generatePrismFromDomain(true);
	
			this.rolePrism = rolePrism;
			this.rolePrism.setTitle(this.title);
			this.rolePrism.setSubTitle(this.subTitle);
			this.rolePrism.setFooter(this.footer);
			this.privilegePrism = privilegePrism;
			this.privilegePrism.setTitle(this.title);
			this.privilegePrism.setSubTitle(this.subTitle);
			this.privilegePrism.setFooter(this.footer);		
		}
	}
	
	private void generateProfilePrismFromUserDomainWithDeniedFields(boolean b,Set<Field> deniedFields) throws Exception{
		if (this.userDomain != null) {
			FindMyProfileUser findProfile = new FindMyProfileUser(this.userDomain,deniedFields);
			ProfileController findProfileController = new ProfileController(findProfile,this.userDomain);
			
			UpdateMyProfileUser updateProfile = new UpdateMyProfileUser(this.userDomain,deniedFields);
			ProfileController updateProfileController = new ProfileController(updateProfile,this.userDomain);
			
			ChangeMyPasswordUser changeMyPassword = new ChangeMyPasswordUser(this.userDomain);
			ProfileController changeMyPasswordController = new ProfileController(changeMyPassword,this.userDomain);

			this.profilePrism.addVerb(findProfile);
			this.profilePrism.addVerb(updateProfile);
			this.profilePrism.addVerb(changeMyPassword);			

			this.profilePrism.getControllers().add(findProfileController);
			this.profilePrism.getControllers().add(updateProfileController);
			this.profilePrism.getControllers().add(changeMyPasswordController);
			
			EasyUIProfilePI eProfile = new EasyUIProfilePI(this.userDomain);
			eProfile.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eProfile.setNav(this.nav);
			this.profilePrism.addPage(eProfile);				
		}		
	}
		
	public void generateLoginPrismFromUserDomain(Boolean ignoreWarning) throws ValidateException, Exception {
		if (this.userDomain != null) {
			LoginUser login = new LoginUser(this.userDomain);
			LoginController loginController = new LoginController(login,this.userDomain);
			
			LogoutUser logout = new LogoutUser(this.userDomain);
			LoginController logoutController = new LoginController(logout,this.userDomain);
			RegisterUser register  = new RegisterUser(this.userDomain,this.roleDomain);
			LoginController registerController = new LoginController(register,this.userDomain);
			
			ReadMySession readMySession = new ReadMySession(this.userDomain);
			readMySession.setRoleDomain(this.roleDomain);
			readMySession.setPrivilegeDomain(this.privilegeDomain);
			LoginController readMySessionController = new LoginController(readMySession,this.userDomain);
			
			Service roleService = new Service();
			roleService.setDomain(this.roleDomain);
			roleService.setStandardName(this.roleDomain.getCapFirstDomainName() + "Service");
			readMySessionController.addOtherService(roleService);
			ChangePasswordUser changePass = new ChangePasswordUser(this.userDomain);
			Controller changePassController = new Controller(changePass,this.userDomain);

			this.loginPrism.getControllers().add(loginController);
			this.loginPrism.getControllers().add(logoutController);
			this.loginPrism.getControllers().add(registerController);
			this.loginPrism.getControllers().add(readMySessionController);
			this.loginPrism.getControllers().add(changePassController);

			EasyUILoginUserIndexPI eIndex = new EasyUILoginUserIndexPI();
			EasyUIErrorPI eErr = new EasyUIErrorPI();
			EasyUIRegisterUserPI eRegister = new EasyUIRegisterUserPI(this.userDomain,this.roleDomain);
			NoAuthPIGenerator npg = new NoAuthPIGenerator();
			npg.setDomain(this.userDomain);
			npg.setTitle(this.title);
			eIndex.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eIndex.setProjectName(this.getProjectName());
			eErr.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eRegister.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eIndex.setDomain(this.userDomain);
			eErr.setDomain(this.userDomain);
			eIndex.setTechnicalStack(this.technicalstack);
			eErr.setTechnicalStack(this.technicalstack);
			eRegister.setTechnicalStack(this.technicalstack);
			npg.setTechnicalStack(this.technicalstack);			
			eErr.setProjectNamePrefix(this.getProjectName());
			eRegister.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			eRegister.setDomain(this.userDomain);
			this.loginPrism.addPage(eIndex);
			this.loginPrism.addPage(eErr);
			this.loginPrism.addPage(eRegister);		
			this.loginPrism.addPage(npg);	
		}
	}
	
	public void decorateUserPrism() throws Exception{
		Domain user = this.getUserDomain();
		ChangePasswordUser changePassword = new ChangePasswordUser(user);
		FindUserShadow findUserShadow = new FindUserShadow(user);
		CountSaltUser countSalt = new CountSaltUser(user,this.dbType);
		RegisterUser register = new RegisterUser(user,this.getRoleDomain());
		LoginUser loginUser = new LoginUser(user);
		LogoutUser logoutUser = new LogoutUser(user);
		
		Set<Verb> verbs = new TreeSet<Verb>();
		verbs.add(changePassword);
		verbs.add(findUserShadow);
		verbs.add(countSalt);
		verbs.add(register);
		verbs.add(loginUser);
		verbs.add(logoutUser);
		decorateVerbsInUserPrism(verbs);
	}
	
	public void decorateLoginPrism() throws Exception{
		Domain user = this.getUserDomain();
		RegisterUser registerUser = new RegisterUser(user,this.roleDomain);
		LoginUser loginUser = new LoginUser(user);
		LogoutUser logoutUser = new LogoutUser(user);
		ChangePasswordUser changePassword = new ChangePasswordUser(user);
		FindUserShadow findShadow = new FindUserShadow(user);
		ReadMySession readMySession = new ReadMySession(user);
		readMySession.setRoleDomain(this.roleDomain);
		readMySession.setPrivilegeDomain(this.privilegeDomain);
		Set<Verb> verbs = new TreeSet<Verb>();
		verbs.add(registerUser);
		verbs.add(loginUser);
		verbs.add(logoutUser);
		verbs.add(changePassword);
		verbs.add(findShadow);
		verbs.add(readMySession);
		decorateVerbsInLoginPrism(verbs);
	}
	
	public void decorateVerbsInUserPrism(Set<Verb> verbs) throws Exception{
		Set<Field> deniedFields = new TreeSet<>();
		for (Field f:this.userDomain.getFields()) {
			if ("password".equals(f.getFixedName())||"salt".equals(f.getFixedName())||"loginFailure".equals(f.getFixedName())) {
				deniedFields.add(f);
			}
		}
	}	
	
	
	public void decorateVerbsInLoginPrism(Set<Verb> verbs) throws Exception{
		if (this.userPrism != null){
			for (Verb verb: verbs){
				this.userPrism.addVerb(verb);
			}
		}
	}

	public Domain getUserDomain() {
		return userDomain;
	}

	public void setUserDomain(Domain userDomain) {
		this.userDomain = userDomain;
	}

	public Domain getRoleDomain() {
		return roleDomain;
	}

	public void setRoleDomain(Domain roleDomain) {
		this.roleDomain = roleDomain;
	}

	public Domain getPrivilegeDomain() {
		return privilegeDomain;
	}

	public void setPrivilegeDomain(Domain privilegeDomain) {
		this.privilegeDomain = privilegeDomain;
	}

	public Prism getUserPrism() {
		return userPrism;
	}

	public void setUserPrism(Prism userPrism) {
		this.userPrism = userPrism;
	}

	public Prism getRolePrism() {
		return rolePrism;
	}

	public void setRolePrism(Prism rolePrism) {
		this.rolePrism = rolePrism;
	}

	public Prism getPrivilegePrism() {
		return privilegePrism;
	}

	public Prism getLoginPrism() {
		return loginPrism;
	}

	public void setPrivilegePrism(Prism privilegePrism) {
		this.privilegePrism = privilegePrism;
	}

	public void setLoginPrism(Prism loginPrism) {
		this.loginPrism = loginPrism;
	}
	
	public static String packagetokenToFolder(String packageToken) {
		String folder = packageToken.replace('.', '/');
		folder += "/";
		return folder;
	}
	
	public static String folderToPackageToken(String folder) {
		String packagetoken = folder.replace('/', '.');
		if (packagetoken.charAt(packagetoken.length() - 1) == '.')
			packagetoken = packagetoken.substring(0, packagetoken.length() - 1);
		return packagetoken;
	}
	
	public void writeToFile(String filePath, String content) throws Exception {
		File f = new File(filePath);
		if (!f.getParentFile().exists()) {
			f.getParentFile().mkdirs();
		}
		f.createNewFile();
		try (Writer fw = new BufferedWriter(
				new OutputStreamWriter(new FileOutputStream(f.getAbsolutePath()), "UTF-8"))) {
			fw.write(content, 0, content.length());
		}
	}
	
	public void generatePrismFiles(Prism prism,Map<String,Boolean> slavesMap,Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException {
		ValidateInfo info = prism.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String srcfolderPath = folderPath + "src/" + Project.packagetokenToFolder(this.packageToken);
			writeToFile(srcfolderPath + Project.packagetokenToFolder(prism.getDomain().getDomainSuffix()) + prism.getDomain().getCapFirstDomainNameWithSuffix()+ ".java", prism.getDomain().generateClassString());
	        
	        if (prism.getDao()!=null && prism.getDao().getDomain() != null){
	        	writeToFile(srcfolderPath + packagetokenToFolder(prism.getDomain().getDaoSuffix()) + StringUtil.capFirst(prism.getDomain().getStandardName())+ "Dao.java", prism.getDao().generateDaoString());
	        }
	        
	        if (prism.getDaoImpl() != null  && prism.getDaoImpl().getDomain() != null) {
	        	writeToFile(srcfolderPath + packagetokenToFolder(prism.getDomain().getDaoimplSuffix()) + StringUtil.capFirst(prism.getDomain().getStandardName())+"DaoImpl.java",prism.getDaoImpl().generateDaoImplString());
	        }
	        
	        if (prism.getService() != null  && prism.getService().getDomain() != null) {
	        	writeToFile(srcfolderPath + packagetokenToFolder(prism.getDomain().getServiceSuffix()) + StringUtil.capFirst(prism.getDomain().getStandardName())+"Service.java", prism.getService().generateServiceString());
	        }
	        
	        if (prism.getServiceImpl() != null  && prism.getServiceImpl().getDomain() != null) {
	        	writeToFile(srcfolderPath + packagetokenToFolder(prism.getDomain().getServiceimplSuffix()) +StringUtil.capFirst(prism.getDomain().getStandardName())+"ServiceImpl.java", prism.getServiceImpl().generateServiceImplString());
	        }
	        
	        for (Controller controller : prism.getControllers()){
				if (controller.generateControllerString()!= null){
					writeToFile(srcfolderPath + packagetokenToFolder(prism.getDomain().getControllerSuffix()) + StringUtil.capFirst(controller.getStandardName())
					+".java", controller.generateControllerString());
				}
	        }
	        
	        for (PrismInterface page : prism.getPages()) {
				page.generatePIFiles(folderPath);
			}

			for (ManyToMany mtm : prism.getManyToManies()) {
				EasyUIMtmPI mPage = mtm.getEuPI();
				mPage.setTechnicalStack(prism.getDomain().getTechnicalStack());
				mPage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
				mPage.setNav(this.getNav());
				mPage.generatePIFiles(folderPath);
			}
		} catch (Exception e){
			e.printStackTrace();
		}
	}	
	
	public void generateDummyPrismFiles(Prism prism,Map<String,Boolean> slavesMap,Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException {
		
	}	

	public String getGenerateData() {
		return generateData;
	}

	public void setGenerateData(String generateData) {
		this.generateData = generateData;
	}
		
	public List<List<Domain>> decorateDataDomains(List<List<Domain>> dataDomains) throws Exception{
		dataDomains = DomainUtil.removeDataDomainsFromLists(dataDomains,this.privilegeDomain.getStandardName());
		long serial = 1L;
		List<Domain> myPrivs = new ArrayList<>();
		Set<Domain> authDomains = new TreeSet<>();
		authDomains.add(this.userDomain);
		authDomains.add(this.roleDomain);
		authDomains.add(this.privilegeDomain);
		
		Set<Domain> privDomains = this.nav.getDomains();
		for (Domain d: privDomains) {
			if (!DomainUtil.inDomainSet(d, authDomains)) {
				Domain priv = (Domain)this.privilegeDomain.deepClone();
				
				for (Field f:priv.getFields()) {
					if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
				
				priv.getDomainId().setFieldValue(""+serial++);
				priv.getDomainName().setFieldValue(d.getStandardName());
				priv.getActive().setFieldValue(this.privilegeDomain.getDomainActiveStr());
				myPrivs.add(priv);
			}
		}
		this.privilegeDomain.setDummyDb(myPrivs);
		dataDomains.add(myPrivs);
		
		boolean isAdminRoleExists = false;
		boolean isUserRoleExists = false;
		List<Domain> myRoles = new ArrayList<>();
		for (List<Domain> datas : dataDomains) {
			for (Domain d : datas) {
				for (Field f:d.getFields()) {
					if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
				
				if (d.getStandardName().equals(this.roleDomain.getStandardName())) {
					myRoles.add(d);
					if (d.getDomainName().getFieldValue().equals("admin")) {
						isAdminRoleExists = true;
						String privsstr = "";
						for (Domain priv : myPrivs) {
							privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
						}
						if (privsstr.endsWith(","))
							privsstr = privsstr.substring(0, privsstr.length() - 1);
						for (ManyToMany mtm : d.getManyToManies()) {
							mtm.setMaster(d);
							mtm.setValues(privsstr);
						}
					}
				}
				if (d.getStandardName().equals(this.roleDomain.getStandardName()) && d.getDomainName().getFieldValue().equals("user")) {
					isUserRoleExists = true;
					String privsstr = "";
					for (Domain priv : myPrivs) {
						privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
					}
					if (privsstr.endsWith(","))
						privsstr = privsstr.substring(0, privsstr.length() - 1);
					for (ManyToMany mtm : d.getManyToManies()) {
						mtm.setMaster(d);
						mtm.setValues(privsstr);
					}
				}
			}
		}
		if (!isAdminRoleExists) {
			Domain adminRole = (Domain)this.roleDomain.deepClone();
			
			for (Field f:adminRole.getFields()) {
				if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
			}
			
			adminRole.getDomainId().setFieldValue("9000");
			adminRole.getDomainName().setFieldValue("admin");
			adminRole.getActive().setFieldValue(adminRole.getDomainActiveStr());
			String privsstr = "";
			for (Domain priv : myPrivs) {
				privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
			}
			if (privsstr.endsWith(","))
				privsstr = privsstr.substring(0, privsstr.length() - 1);
			for (ManyToMany mtm : adminRole.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.privilegeDomain.getStandardName())) {
					mtm.setMasterValue(adminRole.getDomainId().getFieldValue());
					mtm.setMaster(adminRole);
					mtm.setValues(privsstr);
				}
			}
			myRoles.add(adminRole);
		}
		if (!isUserRoleExists) {
			Domain userRole = (Domain)this.roleDomain.deepClone();
			
			for (Field f:userRole.getFields()) {
				if (StringUtil.isBlank(f.getFieldValue())) f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
			}
			
			userRole.getDomainId().setFieldValue("9001");
			userRole.getDomainName().setFieldValue("user");
			userRole.getActive().setFieldValue(userRole.getDomainActiveStr());
			
			String privsstr = "";
			for (Domain priv : myPrivs) {
				privsstr = privsstr + priv.getDomainId().getFieldValue() + ",";
			}
			if (privsstr.endsWith(","))
				privsstr = privsstr.substring(0, privsstr.length() - 1);
			for (ManyToMany mtm : userRole.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.privilegeDomain.getStandardName())) {
					mtm.setMasterValue(userRole.getDomainId().getFieldValue());
					mtm.setMaster(userRole);
					mtm.setValues(privsstr);
				}
			}
			
			myRoles.add(userRole);
		}
		dataDomains = DomainUtil.removeDataDomainsFromLists(dataDomains,this.roleDomain.getStandardName());
		dataDomains.add(myRoles);
		this.roleDomain.setDummyDb(myRoles);
		
		boolean isAdminExists = false;
		boolean isJerryExists = false;
		List<Domain> myUsers = new ArrayList<>();
		List<String> salts = new ArrayList<>();
		for (List<Domain> datas:dataDomains) {
			for (Domain d : datas)
			{		
				if (d.getStandardName().equals(this.userDomain.getStandardName())) {
					for (Field f:d.getFields()) {
						if (f instanceof Dropdown && (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue()))) {
							f.setFieldValue("-1");
						} else if (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue())) {
							f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
						}
					}
					
					String password = d.findFieldByFixedName("password").getFieldValue();
					String salt = PasswordUtil.generateSalt(salts);
					password = PasswordUtil.getPassword(password, salt);
					salts.add(salt);

					d.findFieldByFixedName("password").setFieldValue(password);
					d.findFieldByFixedName("salt").setFieldValue(salt);
					d.findFieldByFixedName("loginFailure").setFieldValue("0");
					myUsers.add(d);
					if (d.getDomainName().getFieldValue().equals("admin")) {
						isAdminExists = true;
						for (ManyToMany mtm : d.getManyToManies()) {
							Domain adminRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "admin");
							if (adminRole != null) {
								String fieldValue = mtm.getValues();
								if (!StringUtil.isBlank(fieldValue)) fieldValue = fieldValue + ","+adminRole.getDomainId().getFieldValue();
								else fieldValue = adminRole.getDomainId().getFieldValue();
								mtm.setMaster(d);
								mtm.setValues(fieldValue);
							}
						}
					}
					if (d.getDomainName().getFieldValue().equals("jerry")) {
						isJerryExists = true;
						for (ManyToMany mtm : d.getManyToManies()) {
							Domain adminRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "user");
							if (adminRole != null) {
								String fieldValue = mtm.getValues();
								if (!StringUtil.isBlank(fieldValue)) fieldValue = fieldValue + ","+adminRole.getDomainId().getFieldValue();
								else fieldValue = adminRole.getDomainId().getFieldValue();
								mtm.setMaster(d);
								mtm.setValues(fieldValue);
							}
						}
					}
				}
			}
		}
		if (!isAdminExists) {
			Domain admin = (Domain)this.userDomain.deepClone();
			
			for (Field f:admin.getFields()) {
				if (f instanceof Dropdown && (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue()))) {
					f.setFieldValue("-1");
				} else if (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue())) {
					f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
			}
			
			admin.getDomainId().setFieldValue("9000");
			admin.getDomainName().setFieldValue("admin");
			admin.getActive().setFieldValue(admin.getDomainActiveStr());
			
			String password = "admin";
			String salt = PasswordUtil.generateSalt(salts);
			password = PasswordUtil.getPassword(password, salt);
			salts.add(salt);
			admin.findFieldByFixedName("password").setFieldValue(password);
			admin.findFieldByFixedName("salt").setFieldValue(salt);
			admin.findFieldByFixedName("loginFailure").setFieldValue("0");
			
			for (ManyToMany mtm : admin.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.roleDomain.getStandardName())) {
					Domain adminRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "admin");
					if (adminRole != null) {
						String fieldValue = adminRole.getDomainId().getFieldValue();
						mtm.setMasterValue(admin.getDomainId().getFieldValue());
						mtm.setMaster(admin);
						mtm.setValues(fieldValue);
					}
				}
			}
			myUsers.add(admin);
		}
		if (!isJerryExists) {
			Domain jerry = (Domain)this.userDomain.deepClone();
			
			for (Field f:jerry.getFields()) {
				if (f instanceof Dropdown && (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue()))) {
					f.setFieldValue("-1");
				} else if (StringUtil.isBlank(f.getFieldValue())||"null".equalsIgnoreCase(f.getFieldValue())) {
					f.setFieldValue(FieldUtil.findTypeDefaultValueString(f.getFieldType()));
				}
			}
			
			jerry.getDomainId().setFieldValue("9001");
			jerry.getDomainName().setFieldValue("jerry");
			jerry.getActive().setFieldValue(jerry.getDomainActiveStr());
			
			String password = "jerry";
			String salt = PasswordUtil.generateSalt(salts);
			password = PasswordUtil.getPassword(password, salt);
			salts.add(salt);
			jerry.findFieldByFixedName("password").setFieldValue(password);
			jerry.findFieldByFixedName("salt").setFieldValue(salt);
			jerry.findFieldByFixedName("loginFailure").setFieldValue("0");
			
			for (ManyToMany mtm : jerry.getManyToManies()) {
				if (mtm.getSlaveAlias().equals(this.roleDomain.getStandardName())) {
					Domain userRole = DomainUtil.findDataDomainInListByDomainNameValue(myRoles, "user");
					if (userRole != null) {
						String fieldValue = userRole.getDomainId().getFieldValue();
						mtm.setMasterValue(jerry.getDomainId().getFieldValue());
						mtm.setMaster(jerry);
						mtm.setValues(fieldValue);
					}
				}
			}
			myUsers.add(jerry);
		}
		dataDomains = DomainUtil.removeDataDomainsFromLists(dataDomains,this.userDomain.getStandardName());
		dataDomains.add(myUsers);
		this.userDomain.setDummyDb(myUsers);
		return dataDomains;
	}
	
	@Override
	public void setNav(Nav nav) {
		super.setNav(nav);
		if (this.userPrism!=null) {
			for (PrismInterface page:this.userPrism.getPages()) {
				page.setNav(nav);
			}
		}
		if (this.rolePrism!=null) {
			for (PrismInterface page:this.rolePrism.getPages()) {
				page.setNav(nav);
			}
		}
		if (this.privilegePrism!=null) {
			for (PrismInterface page:this.privilegePrism.getPages()) {
				page.setNav(nav);
			}
		}
		for (PrismInterface page:this.profilePrism.getPages()) {
			page.setNav(nav);
		}
	}
	
	@Override
	public Nav getNav() {
		return super.getNav();
	}
	
	public void generateUserPrismFromUserDomainWithDeniedFields(Boolean ignoreWarning,Set<Field> deniedFields) throws ValidateException, Exception {
		if (this.userDomain != null) {
			if (this.getPackageToken() != null) {
				this.userDomain.setPackageToken(packageToken);
			}
			
			this.userDomain.decorateCompareTo();

			Dao dao = new Dao();
			dao.setPackageToken(this.userDomain.getPackageToken());
			dao.setDomain(this.userDomain);
			this.userPrism.setDao(dao);

			DaoImpl daoimpl = new DaoImpl();
			daoimpl.setPackageToken(this.userDomain.getPackageToken());
			daoimpl.setDomain(this.userDomain);
			this.userPrism.setDaoImpl(daoimpl);
			
			// DummyDaoImpl dummydaoimpl = new DummyDaoImpl();
			// dummydaoimpl.setPackageToken(this.userDomain.getPackageToken());
			// dummydaoimpl.setDomain(this.userDomain);
			// this.userPrism.setDummydaoimpl(dummydaoimpl);
			
			Service service = new Service();
			service.setDomain(this.userDomain);
			service.setPackageToken(this.userDomain.getPackageToken());
			ServiceImpl serviceimpl = new ServiceImpl(this.userDomain);
			serviceimpl.setPackageToken(this.userDomain.getPackageToken());
			serviceimpl.setDomain(this.userDomain);
			Service roleService = new Service();
			roleService.setDomain(this.roleDomain);
			roleService.setStandardName(this.roleDomain.getCapFirstDomainName() + "Service");
			this.userPrism.setService(service);
			serviceimpl.addOtherService(roleService);
			this.userPrism.setServiceImpl(serviceimpl);

			ListAll listAll = new ListAll(this.userDomain,deniedFields);	
			Verb update = this.userDomain.hasDomainId() ?new Update(this.userDomain,deniedFields):null;
			Verb delete = this.userDomain.hasDomainId() ?new Delete(this.userDomain):null;
			AddUser addUser = this.userDomain.hasDomainId() ?new AddUser(this.userDomain,this.roleDomain):null;
			Verb softdelete = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new SoftDelete(this.userDomain):null;
			FindById findbyid = this.userDomain.hasDomainId() ? new FindById(this.userDomain,deniedFields):null;
			FindByName findbyname = this.userDomain.hasDomainName() ? new FindByName(this.userDomain,deniedFields):null;
			ListActive listactive = this.userDomain.hasActiveField()?new ListActive(this.userDomain, deniedFields):null;
			Verb deleteAll = this.userDomain.hasDomainId() ?new DeleteAll(this.userDomain):null;
			Verb softDeleteAll = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new SoftDeleteAll(this.userDomain):null;
			Verb toggle = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new Toggle(this.userDomain):null;
			Verb toggleOne = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new ToggleOne(this.userDomain):null;
			SearchByFieldsByPage searchByFieldsByPage = new SearchByFieldsByPage(this.userDomain,deniedFields);
			Verb activate = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new Activate(this.userDomain):null;
			Verb activateAll = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ?new ActivateAll(this.userDomain):null;
			Verb export = new Export(this.userDomain,deniedFields);
			Verb exportPDF = new ExportPDF(this.userDomain,deniedFields);
			Verb exportPPT  = new ExportPPT(this.userDomain,deniedFields);
			Verb exportWord  = new ExportWord(this.userDomain,deniedFields);
			Verb view = new View(this.userDomain,deniedFields);
			
			SearchByFields searchByFields = new SearchByFields(this.userDomain,deniedFields);
			Verb filterExcel = new FilterExcel(this.userDomain,deniedFields);
			Verb filterPDF = new FilterPDF(this.userDomain,deniedFields);
			Verb filterPPT = new FilterPPT(this.userDomain,deniedFields);
			Verb filterWord = new FilterWord(this.userDomain,deniedFields);
		
			Verb clone	= this.userDomain.hasDomainId() ?new Clone(this.userDomain):null;
			Verb findFullInfoById = this.userDomain.hasDomainId() ?new FindFullInfoById(this.userDomain):null;
			Verb searchIndexedNamesByShortName = this.userDomain.hasDomainId() ?new SearchIndexedNamesByShortName(this.userDomain):null;
			Verb cloneAll = this.userDomain.hasDomainId()  ?new CloneAll(this.userDomain):null;
			Verb checkAccess = new CheckAccess(this.userDomain);
			
			CountSearchByFieldsRecords countSearchByFieldsRecords = new CountSearchByFieldsRecords(this.userDomain);
			//countSearchByFieldsRecords.setDeniedFields(deniedFields);
			CountAllRecords countAllRecords = new CountAllRecords(this.userDomain);
			CountActiveRecords countActiveRecords = this.userDomain.hasDomainId() && this.userDomain.hasActiveField() ? new CountActiveRecords(this.userDomain):null;

			for (Field f:this.userDomain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					AddUploadDomainField addUpload = new AddUploadDomainField(this.userDomain,f);
					addUpload.setBelongsToUserDomain(true);
					this.userPrism.getDomainFieldVerbs().add(addUpload);
					UpdateUploadDomainField updateUpload = new UpdateUploadDomainField(this.userDomain,f);
					updateUpload.setBelongsToUserDomain(true);
					this.userPrism.getDomainFieldVerbs().add(updateUpload);
				}
			}
			
			this.userPrism.addVerb(listAll);
			this.userPrism.addVerb(update);
			this.userPrism.addVerb(delete);
			this.userPrism.addVerb(addUser);
			this.userPrism.addVerb(softdelete);
			this.userPrism.addVerb(findbyid);
			this.userPrism.addVerb(findbyname);
			this.userPrism.addVerb(listactive);
			this.userPrism.addVerb(deleteAll);
			this.userPrism.addVerb(softDeleteAll);
			this.userPrism.addVerb(toggle);
			this.userPrism.addVerb(toggleOne);
			this.userPrism.addVerb(searchByFieldsByPage);
			this.userPrism.addVerb(activate);
			this.userPrism.addVerb(activateAll);
			this.userPrism.addVerb(export);
			this.userPrism.addVerb(exportPDF);
			this.userPrism.addVerb(exportPPT);
			this.userPrism.addVerb(exportWord);
			this.userPrism.addVerb(view);
			this.userPrism.addVerb(searchByFields);
			this.userPrism.addVerb(filterExcel);
			this.userPrism.addVerb(filterPDF);
			this.userPrism.addVerb(filterPPT);
			this.userPrism.addVerb(filterWord);
			this.userPrism.addVerb(clone);
			this.userPrism.addVerb(findFullInfoById);
			this.userPrism.addVerb(searchIndexedNamesByShortName);
			this.userPrism.addVerb(cloneAll);
			this.userPrism.addVerb(checkAccess);

			this.userPrism.addNoControllerVerb(countSearchByFieldsRecords);
			this.userPrism.addNoControllerVerb(countAllRecords);
			if (countActiveRecords !=null) this.userPrism.addNoControllerVerb(countActiveRecords);

			for (Verb v : this.userPrism.getVerbs()) {
				v.setDomain(userDomain);
				v.setDbType(this.dbType);
				if (!(v instanceof LoginUser || v instanceof LogoutUser || v instanceof ReadMySession || v instanceof RegisterUser)){
					this.userPrism.getControllers().add(new Controller(v,this.userDomain));
				}
				service.addMethod(v.generateServiceMethodDefinition());
				serviceimpl.addMethod(v.generateServiceImplMethod());
				dao.addMethod(v.generateDaoMethodDefinition());
				daoimpl.addMethod(v.generateDaoImplMethod());
				//dummydaoimpl.addMethoPd(v.generateDummyDaoImplMethod());
			}

			for (NoControllerVerb nVerb : this.userPrism.getNoControllerVerbs()) {
				nVerb.setDomain(userDomain);
				if (! (nVerb instanceof CountActiveRecords)) {
					service.addMethod(nVerb.generateServiceMethodDefinition());
					serviceimpl.addMethod(nVerb.generateServiceImplMethod());
				}
				dao.addMethod(nVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(nVerb.generateDaoImplMethod());
				//dummydaoimpl.addMethod(nVerb.generateDummyDaoImplMethod());
			}

			for (DaoOnlyVerb oVerb : this.userPrism.getDaoOnlyVerbs()) {
				oVerb.setDomain(userDomain);
				dao.addMethod(oVerb.generateDaoMethodDefinition());
				daoimpl.addMethod(oVerb.generateDaoImplMethod());
				//dummydaoimpl.addMethod(oVerb.generateDummyDaoImplMethod());
			}
			
			for (DomainFieldVerb dfv:this.userPrism.getDomainFieldVerbs()) {
				dfv.setBelongsToUserDomain(true);
				DomainFieldController dfc = new DomainFieldController(dfv);
				this.userPrism.getControllers().add(dfc);
			}

			EasyUIUserPagePI easyui = new EasyUIUserPagePI(this.userDomain,this.roleDomain);
			easyui.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			easyui.setDomain(this.userDomain);
			easyui.setTechnicalStack(this.technicalstack);
			this.userPrism.addPage(easyui);

			if (this.userDomain.getManyToManies() != null && this.userDomain.getManyToManies().size() > 0) {
				for (ManyToMany mtm : this.userDomain.getManyToManies()) {
					String slaveName = mtm.getManyToManySalveName();
					String masterName = this.userDomain.getStandardName();
					if (DomainUtil.listContainsDomain(this.getDomains(), masterName)
							&& DomainUtil.listContainsDomain(this.getDomains(), slaveName)) {
						Domain tempo = DomainUtil.lookupDomainInList(this.getDomains(), slaveName);
						Domain myslave = tempo==null?null:(Domain)tempo.deepClone();
						if (myslave == null) continue;
						if (!StringUtil.isBlank(mtm.getSlaveAlias())){
							myslave.setAlias(mtm.getSlaveAlias());
							myslave.setAliasLabel(mtm.getSlaveAliasLabel());
						}
						ManyToMany mymtm = new ManyToMany(DomainUtil.lookupDomainInList(this.getDomains(), masterName),
								myslave,mtm.getMasterValue(),mtm.getValues());	
						mymtm.setSlaveAlias(myslave.getAlias());
						mymtm.setSlaveAliasLabel(mtm.getSlaveAliasLabel());
						mymtm.setValues(mtm.getValues());
						this.userPrism.getManyToManies().add(mymtm);
					} else {
						ValidateInfo validateInfo = new ValidateInfo();
						validateInfo.addCompileError("棱柱" + this.userPrism.getText() + "多对多设置有误。");
						ValidateException em = new ValidateException(validateInfo);
						throw em;
					}
				}
			}
			for (ManyToMany mtm : this.userPrism.getManyToManies()) {
				this.userPrism.getService().addMethod(mtm.getAssign().generateServiceMethodDefinition());
				this.userPrism.getServiceimpl().addMethod(mtm.getAssign().generateServiceImplMethod());
				this.userPrism.getDao().addMethod(mtm.getAssign().generateDaoMethodDefinition());
				this.userPrism.getDaoimpl().addMethod(mtm.getAssign().generateDaoImplMethod());
				TwoDomainController tcontroller = new TwoDomainController(mtm.getAssign(),mtm.getMaster(),mtm.getSlave());
				this.userPrism.getControllers().add(tcontroller);

				this.userPrism.getService().addMethod(mtm.getRevoke().generateServiceMethodDefinition());
				this.userPrism.getServiceimpl().addMethod(mtm.getRevoke().generateServiceImplMethod());
				this.userPrism.getDao().addMethod(mtm.getRevoke().generateDaoMethodDefinition());
				this.userPrism.getDaoimpl().addMethod(mtm.getRevoke().generateDaoImplMethod());
				TwoDomainController tcontroller2 = new TwoDomainController(mtm.getRevoke(),mtm.getMaster(),mtm.getSlave());
				this.userPrism.getControllers().add(tcontroller2);

				this.userPrism.getService().addMethod(mtm.getListMyActive().generateServiceMethodDefinition());
				this.userPrism.getServiceimpl().addMethod(mtm.getListMyActive().generateServiceImplMethod());
				this.userPrism.getDao().addMethod(mtm.getListMyActive().generateDaoMethodDefinition());
				this.userPrism.getDaoimpl().addMethod(mtm.getListMyActive().generateDaoImplMethod());
				TwoDomainController tcontroller3 = new TwoDomainController(mtm.getListMyActive(),mtm.getMaster(),mtm.getSlave());
				this.userPrism.getControllers().add(tcontroller3);

				this.userPrism.getService().addMethod(mtm.getListMyAvailableActive().generateServiceMethodDefinition());
				this.userPrism.getServiceimpl().addMethod(mtm.getListMyAvailableActive().generateServiceImplMethod());
				this.userPrism.getDao().addMethod(mtm.getListMyAvailableActive().generateDaoMethodDefinition());
				this.userPrism.getDaoimpl().addMethod(mtm.getListMyAvailableActive().generateDaoImplMethod());
				TwoDomainController tcontroller4 = new TwoDomainController(mtm.getListMyAvailableActive(),mtm.getMaster(),mtm.getSlave());
				this.userPrism.getControllers().add(tcontroller4);
				
				mtm.getSlave().decorateCompareTo();
				
				Service slaveService = new Service();
				slaveService.setDomain(mtm.getSlave());
				slaveService.setStandardName(mtm.getSlave().getCapFirstDomainName() + "Service");
				
				Method slaveServiceSetter = NamedUtilMethodGenerator.generateSetter(mtm.getSlave().getLowerFirstDomainName()+"Service",
						new Type(mtm.getSlave().getCapFirstDomainName() + "Service",mtm.getSlave().getPackageToken()+"."+mtm.getSlave().getServiceSuffix()+"."+mtm.getSlave().getCapFirstDomainName() + "Service"));
				this.userPrism.getServiceimpl().addMethod(slaveServiceSetter);
				this.userPrism.getServiceimpl().addClassImports(mtm.getSlave().getPackageToken()+"."+mtm.getSlave().getServiceimplSuffix()+"."+mtm.getSlave().getCapFirstDomainName() + "ServiceImpl");
				this.userPrism.getServiceimpl().addOtherService(slaveService);
			}
		}

		if (this.userDomain.getManyToManies() != null && this.userDomain.getManyToManies().size() > 0) {
			for (ManyToMany mtm : this.userDomain.getManyToManies()) {
				String slaveName = mtm.getManyToManySalveName();
				String masterName = this.userDomain.getStandardName();
				if (DomainUtil.setContainsDomain(this.userPrism.getProjectDomains(), masterName)
						&& DomainUtil.setContainsDomain(this.userPrism.getProjectDomains(), slaveName)) {
					Domain tempo = DomainUtil.lookupDomainInSet(this.userPrism.getProjectDomains(), slaveName);
					Domain myslave = tempo==null?null:(Domain)tempo.deepClone();
					if (myslave == null) continue;
					myslave.setAlias(myslave.getCapFirstDomainName());
					myslave.setAliasLabel(myslave.getText());
					if (!StringUtil.isBlank(mtm.getSlaveAlias())){
						myslave.setAlias(mtm.getSlaveAlias());
						myslave.setAliasLabel(mtm.getSlaveAliasLabel());
					}
					ManyToMany mymtm = new ManyToMany(DomainUtil.lookupDomainInSet(this.userPrism.getProjectDomains(), masterName),
							myslave,mtm.getMasterValue(),mtm.getValues());	
					mymtm.setSlaveAlias(myslave.getAlias());
					mymtm.setSlaveAliasLabel(mtm.getSlaveAliasLabel());
					mymtm.setValues(mtm.getValues());
					this.userPrism.getManyToManies().add(mymtm);
				} else {
					ValidateInfo validateInfo = new ValidateInfo();
					validateInfo.addCompileError("棱柱" + this.userPrism.getText() + "多对多设置有误。");
					ValidateException em = new ValidateException(validateInfo);
					throw em;
				}
			}
		}
	}

	public Map<String, Boolean> getSlavesMap() {
		return slavesMap;
	}

	public void setSlavesMap(Map<String, Boolean> slavesMap) {
		this.slavesMap = slavesMap;
	}
}